﻿using System;

#if WINDOWS_PHONE
namespace Fibre.WP7.Threading
#else
#if SILVERLIGHT
namespace Fibre.Silverlight.Threading
#else
namespace Fibre.Threading
#endif
#endif
{
    public interface IAddWork
    {
        /// <summary>
        /// Adds additional work to the AsyncWork. Will be performed concurrently with this work.
        /// </summary>
        /// <param name="work">An action to perform asynchronously</param>
        /// <returns>Work context to register completion callbacks and chain more work</returns>
        IWorkContext AddWork(Action work);

        /// <summary>
        /// Adds additional work to the AsyncWork. Will be performed concurrently with this work.
        /// </summary>
        /// <param name="work">Async Pattern Begin method with no parameters</param>
        /// <param name="complete">Async Pattern End method with no return value</param>
        /// <returns>Work context to register completion callbacks and chain more work</returns>
        IWorkContext AddWork(Func<AsyncCallback, object, IAsyncResult> work, Action<IAsyncResult> complete);

        /// <summary>
        /// Adds additional work to the AsyncWork. Will be performed concurrently with this work.
        /// </summary>
        /// <param name="work">Async Pattern Begin method with a single parameter.</param>
        /// <param name="asyncArgument">Async Pattern Begin method parameter</param>
        /// <param name="complete">Async Pattern End method with no return value</param>
        /// <returns>Work context to register completion callbacks and chain more work</returns>
        IWorkContext AddWork<TArg>(Func<TArg, AsyncCallback, object, IAsyncResult> work, TArg asyncArgument, Action<IAsyncResult> complete);

        /// <summary>
        /// Adds additional work to the AsyncWork. Will be performed concurrently with this work.
        /// </summary>
        /// <param name="work">The function to be performed asynchronously.</param>
        /// <returns>Result of the work</returns>
        IWorkContext<TResult> AddWork<TResult>(Func<TResult> work);

        /// <summary>
        /// Adds additional work to the AsyncWork. Will be performed concurrently with this work.
        /// </summary>
        /// <param name="work">Async Pattern Begin method with no parameters</param>
        /// <param name="complete">Async Pattern End method with a return value of TResult</param>
        /// <returns>Work context to register completion callbacks and chain more work</returns>
        IWorkContext<TResult> AddWork<TResult>(Func<AsyncCallback, object, IAsyncResult> work, Func<IAsyncResult, TResult> complete);


        /// <summary>
        /// Adds additional work to the AsyncWork. Will be performed concurrently with this work.
        /// </summary>
        /// <param name="work">Async Pattern Begin method with a single argument</param>
        /// <param name="asyncArgument">Async Pattern Begin method parameter</param>
        /// <param name="complete">Async Pattern End method with a return value of TResult</param>
        /// <returns>Work context to register completion callbacks and chain more work</returns>
        IWorkContext<TResult> AddWork<TArg, TResult>(
            Func<TArg, AsyncCallback, object, IAsyncResult> work,
            TArg asyncArgument,
            Func<IAsyncResult, TResult> complete);

        /// <summary>
        /// Adds additional work to the AsyncWork. Will be performed concurrently with this work.
        /// </summary>
        /// <param name="work">Async Pattern Begin method with a single argument</param>
        /// <param name="asyncArgument">Async Pattern Begin method parameter</param>
        /// <param name="asyncArgument2">Async Pattern Begin method second parameter</param>
        /// <param name="complete">Async Pattern End method with a return value of TResult</param>
        /// <returns>Work context to register completion callbacks and chain more work</returns>
        IWorkContext AddWork<TArg, TArg2>(
            Func<TArg, TArg2, AsyncCallback, object, IAsyncResult> work,
            TArg asyncArgument,
            TArg2 asyncArgument2,
            Action<IAsyncResult> complete);

        /// <summary>
        /// Adds additional work to the AsyncWork. Will be performed concurrently with this work.
        /// </summary>
        /// <param name="work">Async Pattern Begin method with a single argument</param>
        /// <param name="asyncArgument">Async Pattern Begin method parameter</param>
        /// <param name="asyncArgument2">Async Pattern Begin method second parameter</param>
        /// <param name="complete">Async Pattern End method with a return value of TResult</param>
        /// <returns>Work context to register completion callbacks and chain more work</returns>
        IWorkContext<TResult> AddWork<TArg, TArg2, TResult>(
            Func<TArg, TArg2, AsyncCallback, object, IAsyncResult> work,
            TArg asyncArgument,
            TArg2 asyncArgument2,
            Func<IAsyncResult, TResult> complete);
    }
}
